// boost
#include <boost/iostreams/stream_buffer.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>

// std
#include <sys/ioctl.h>  // for ioctl() and FIONREAD


namespace process {
  namespace detail {

    namespace io = boost::iostreams;

    class stream_buffer : public io::stream_buffer<io::file_descriptor_source>
    {
    public:
      stream_buffer(int fd) :
        io::stream_buffer<io::file_descriptor_source>(fd, true),
        m_fd(fd)
      { }

    protected:
      std::streamsize showmanyc()
      {
        int avail = 0;
#ifdef FIONREAD
        if (ioctl(m_fd, FIONREAD, &avail) == -1)
          avail = -1;
#endif
        return std::streamsize(avail);
      }

    private:
      int m_fd;
    };

    class istream : public std::istream
    {
    public:
      istream(int fd) :
        std::istream(0), buf(fd)
      {
        rdbuf(&buf);
      }
    private:
      stream_buffer buf;
    };


  } // namespace detail
} // namespace process
